Micron Document
<!DOCTYPE html>
<html class="client-nojs vector-feature-night-mode-disabled vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-1 vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-1 vector-sticky-header-enabled" lang="en" dir="ltr"><head>
<meta charset="UTF-8">
<title>Locality of reference</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="canonical" href="https://en.wikipedia.org/wiki/Locality_of_reference"> <link href="./mw/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/skins.vector.styles.css" rel="stylesheet" type="text/css">
<link href="./mw/user.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link rel="stylesheet" type="text/css" href="./mw/site.styles.css">
<link rel="stylesheet" type="text/css" href="./mw/noscript.css">
<link rel="stylesheet" type="text/css" href="./footer.css">
<link rel="stylesheet" type="text/css" href="./vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-Locality_of_reference rootpage-Locality_of_reference skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading">
<span id="openzim-page-title" class="mw-page-title-main"><span class="mw-page-title-main">Locality of reference</span></span>
</h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="en" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="en" dir="ltr">
<style data-mw-deduplicate="TemplateStyles:r1251242444">
/* start https://en.wikipedia.org/ */


.mw-parser-output .ambox{border:1px solid #a2a9b1;border-left:10px solid #36c;background-color:#fbfbfb;box-sizing:border-box}.mw-parser-output .ambox+link+.ambox,.mw-parser-output .ambox+link+style+.ambox,.mw-parser-output .ambox+link+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+style+.ambox,.mw-parser-output .ambox+.mw-empty-elt+link+link+.ambox{margin-top:-1px}html body.mediawiki .mw-parser-output .ambox.mbox-small-left{margin:4px 1em 4px 0;overflow:hidden;width:238px;border-collapse:collapse;font-size:88%;line-height:1.25em}.mw-parser-output .ambox-speedy{border-left:10px solid #b32424;background-color:#fee7e6}.mw-parser-output .ambox-delete{border-left:10px solid #b32424}.mw-parser-output .ambox-content{border-left:10px solid #f28500}.mw-parser-output .ambox-style{border-left:10px solid #fc3}.mw-parser-output .ambox-move{border-left:10px solid #9932cc}.mw-parser-output .ambox-protection{border-left:10px solid #a2a9b1}.mw-parser-output .ambox .mbox-text{border:none;padding:0.25em 0.5em;width:100%}.mw-parser-output .ambox .mbox-image{border:none;padding:2px 0 2px 0.5em;text-align:center}.mw-parser-output .ambox .mbox-imageright{border:none;padding:2px 0.5em 2px 0;text-align:center}.mw-parser-output .ambox .mbox-empty-cell{border:none;padding:0;width:1px}.mw-parser-output .ambox .mbox-image-div{width:52px}@media(min-width:720px){.mw-parser-output .ambox{margin:0 10%}}@media print{body.ns-0 .mw-parser-output .ambox{display:none!important}}


/* end https://en.wikipedia.org/ */
</style>
<p>In <a href="Computer_science" title="Computer science">computer science</a>, <b>locality of reference</b>, also known as the <b>principle of locality</b>,<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup> is the tendency of a processor to access the same set of memory locations repetitively over a short period of time.<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup> There are two basic types of reference locality – temporal and spatial locality. Temporal locality refers to the reuse of specific data and/or resources within a relatively small time duration. Spatial locality (also termed <i>data locality</i>)<sup id="cite_ref-NistBig1_3-0" class="reference"><a href="#cite_note-NistBig1-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup> refers to the use of data elements within relatively close storage locations. Sequential locality, a special case of spatial locality, occurs when data elements are arranged and accessed linearly, such as traversing the elements in a one-dimensional <a href="Array_data_structure" class="mw-redirect" title="Array data structure">array</a>.
</p><p>Locality is a type of <a href="Predictability" title="Predictability">predictable</a> behavior that occurs in computer systems. Systems which exhibit strong <i>locality of reference</i> are good candidates for performance optimization through the use of techniques such as the <a href="CPU_cache" title="CPU cache">caching</a>, <a href="Prefetch_instruction" class="mw-redirect" title="Prefetch instruction">prefetching</a> for memory and advanced <a href="Branch_predictor" title="Branch predictor">branch predictors</a> of a processor core.
</p>
<meta property="mw:PageProp/toc">
<div class="mw-heading mw-heading2"><h2 id="Types_of_locality">Types of locality</h2></div>
<p>There are several different types of locality of reference:
</p>
<ul><li><b>Temporal locality</b>: If at one point a particular memory location is referenced, then it is likely that the same location will be referenced again in the near future. There is temporal proximity between adjacent references to the same memory location. In this case it is common to make efforts to store a copy of the referenced data in faster memory storage, to reduce the latency of subsequent references. Temporal locality is a special case of spatial locality (see below), namely when the prospective location is identical to the present location.</li>
<li><b>Spatial locality</b>: If a particular storage location is referenced at a particular time, then it is likely that nearby memory locations will be referenced in the near future. In this case it is common to attempt to guess the size and shape of the area around the current reference for which it is worthwhile to prepare faster access for subsequent reference.
<ul><li><b>Memory locality</b> (or <i>data locality</i><sup id="cite_ref-NistBig1_3-1" class="reference"><a href="#cite_note-NistBig1-3"><span class="cite-bracket">[</span>3<span class="cite-bracket">]</span></a></sup>): Spatial locality explicitly relating to <a href="Computer_memory" title="Computer memory">memory</a>.</li></ul></li>
<li><b><a href="Branch_(computer_science)" title="Branch (computer science)">Branch</a> locality</b>: If there are only a few possible alternatives for the prospective part of the path in the spatial-temporal coordinate space. This is the case when an instruction loop has a simple structure, or the possible outcome of a small system of conditional branching instructions is restricted to a small set of possibilities. Branch locality is typically not spatial locality since the few possibilities can be located far away from each other.</li>
<li><b>Equidistant locality</b>: Halfway between spatial locality and branch locality. Consider a loop accessing locations in an equidistant pattern, i.e., the path in the spatial-temporal coordinate space is a dotted line. In this case, a simple linear function can predict which location will be accessed in the near future.</li></ul>
<p>In order to benefit from temporal and spatial locality, which occur frequently, most of the information storage systems are <a href="Computer_data_storage#Hierarchy_of_storage" title="Computer data storage">hierarchical</a>. Equidistant locality is usually supported by a processor's diverse nontrivial increment instructions. For branch locality, the contemporary processors have sophisticated branch predictors, and on the basis of this prediction the memory manager of the processor tries to collect and preprocess the data of plausible alternatives.
</p>
<div class="mw-heading mw-heading2"><h2 id="Relevance">Relevance</h2></div>
<p>There are several reasons for locality. These reasons are either goals to achieve or circumstances to accept, depending on the aspect. The reasons below are not <a href="Disjoint_sets" title="Disjoint sets">disjoint</a>; in fact, the list below goes from the most general case to special cases:
</p>
<ul><li><b>Predictability</b>: Locality is merely one type of predictable behavior in computer systems.</li>
<li><b>Structure of the program</b>: Locality occurs often because of the way in which computer programs are created, for handling decidable problems. Generally, related data is stored in nearby locations in storage. One common pattern in computing involves the processing of several items, one at a time. This means that if a lot of processing is done, the single item will be accessed more than once, thus leading to temporal locality of reference. Furthermore, moving to the next item implies that the next item will be read, hence spatial locality of reference, since memory locations are typically read in batches.</li>
<li><b>Linear data structures</b>: Locality often occurs because code contains loops that tend to reference arrays or other data structures by indices. Sequential locality, a special case of spatial locality, occurs when relevant data elements are arranged and accessed linearly. For example, the simple traversal of elements in a one-dimensional array, from the base address to the highest element would exploit the sequential locality of the array in memory.<sup id="cite_ref-4" class="reference"><a href="#cite_note-4"><span class="cite-bracket">[</span>4<span class="cite-bracket">]</span></a></sup> Equidistant locality occurs when the linear traversal is over a longer area of adjacent <a href="Data_structure" title="Data structure">data structures</a> with identical structure and size, accessing mutually corresponding elements of each structure rather than each entire structure. This is the case when a <a href="Matrix_(mathematics)" title="Matrix (mathematics)">matrix</a> is represented as a sequential matrix of rows and the requirement is to access a single column of the matrix.</li>
<li><b>Efficiency of memory hierarchy use</b>: Although <a href="Random-access_memory" title="Random-access memory">random-access memory</a> presents the programmer with the ability to read or write anywhere at any time, in practice <a href="Latency_(engineering)" title="Latency (engineering)">latency</a> and throughput are affected by the efficiency of the <a href="Cache_(computing)" title="Cache (computing)">cache</a>, which is improved by increasing the locality of reference. Poor locality of reference results in cache <a href="Thrashing_(computer_science)" title="Thrashing (computer science)">thrashing</a> and <a href="Cache_pollution" title="Cache pollution">cache pollution</a> and to avoid it, data elements with poor locality can be bypassed from cache.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="General_usage">General usage</h2></div>
<p>If most of the time the substantial portion of the references aggregate into clusters, and if the shape of this system of clusters can be well predicted, then it can be used for performance optimization. There are several ways to benefit from locality using <a href="Optimization_(computer_science)" class="mw-redirect" title="Optimization (computer science)">optimization</a> techniques. Common techniques are:
</p>
<ul><li>Increasing the locality of references (generally on the software side)</li>
<li>Exploiting the locality of references: Generally achieved on the hardware side, temporal and spatial locality can be capitalized by hierarchical storage hardware. The equidistant locality can be used by the appropriately specialized instructions of the processors, this possibility is not only the responsibility of hardware, but the software as well, whether its structure is suitable for compiling a binary program that calls the specialized instructions in question. The branch locality is a more elaborate possibility, hence more developing effort is needed, but there is much larger reserve for future exploration in this kind of locality than in all the remaining ones.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Spatial_and_temporal_locality_usage">Spatial and temporal locality usage</h2></div>
<div class="mw-heading mw-heading3"><h3 id="Hierarchical_memory">Hierarchical memory</h3></div>
<style data-mw-deduplicate="TemplateStyles:r1236090951">
/* start https://en.wikipedia.org/ */


.mw-parser-output .hatnote{font-style:italic}.mw-parser-output div.hatnote{padding-left:1.6em;margin-bottom:0.5em}.mw-parser-output .hatnote i{font-style:normal}.mw-parser-output .hatnote+link+.hatnote{margin-top:-0.5em}@media print{body.ns-0 .mw-parser-output .hatnote{display:none!important}}


/* end https://en.wikipedia.org/ */
</style><div role="note" class="hatnote navigation-not-searchable">Main article: <a href="Memory_hierarchy" title="Memory hierarchy">Memory hierarchy</a></div>
<p>Hierarchical memory is a hardware optimization that takes the benefits of spatial and temporal locality and can be used on several levels of the memory hierarchy. <a href="Paging" class="mw-redirect" title="Paging">Paging</a> obviously benefits from temporal and spatial locality. A cache is a simple example of exploiting temporal locality, because it is a specially designed, faster but smaller memory area, generally used to keep recently referenced data and data near recently referenced data, which can lead to potential performance increases.
</p><p>Data elements in a cache do not necessarily correspond to data elements that are spatially close in the main memory; however, data elements are brought into cache one <a href="Cache_line" class="mw-redirect" title="Cache line">cache line</a> at a time. This means that spatial locality is again important: if one element is referenced, a few neighboring elements will also be brought into cache. Finally, temporal locality plays a role on the lowest level, since results that are referenced very closely together can be kept in the <a href="Processor_register" title="Processor register">machine registers</a>. Some programming languages (such as <a href="C_(programming_language)" title="C (programming language)">C</a>) allow the programmer to suggest that certain variables be kept in registers.
</p><p>Data locality is a typical memory reference feature of regular programs (though many irregular memory access patterns exist). It makes the hierarchical memory layout profitable. In computers, memory is divided into a hierarchy in order to speed up data accesses. The lower levels of the memory hierarchy tend to be slower, but larger. Thus, a program will achieve greater performance if it uses memory while it is cached in the upper levels of the memory hierarchy and avoids bringing other data into the upper levels of the hierarchy that will displace data that will be used shortly in the future. This is an ideal, and sometimes cannot be achieved.
</p><p>Typical memory hierarchy (access times and cache sizes are approximations of typical values used as of 2013 for the purpose of discussion; actual values and actual numbers of levels in the hierarchy vary):
</p>
<ul><li><a href="CPU_register" class="mw-redirect" title="CPU register">CPU registers</a> (8–256 registers) – immediate access, with the speed of the innermost core of the processor</li>
<li>L1 <a href="CPU_cache" title="CPU cache">CPU caches</a> (32&nbsp;KB to 512&nbsp;<a href="Kilobyte" title="Kilobyte">KB</a>) – fast access, with the speed of the innermost memory bus owned exclusively by each core</li>
<li>L2 CPU caches (128&nbsp;KB to 24&nbsp;<a href="Megabyte" title="Megabyte">MB</a>) – slightly slower access, with the speed of the <a href="Memory_bus" class="mw-redirect" title="Memory bus">memory bus</a> shared between twins of cores</li>
<li>L3 CPU caches (2&nbsp;MB up to a max of 64&nbsp;<a href="Megabyte" title="Megabyte">MB</a>) – even slower access, with the speed of the memory bus shared between even more cores of the same processor</li>
<li>Main <a href="Physical_memory" class="mw-redirect" title="Physical memory">physical memory</a> (<a href="Random-access_memory" title="Random-access memory">RAM</a>) (256&nbsp;MB to 64&nbsp;<a href="Gigabyte" title="Gigabyte">GB</a>) – slow access, the speed of which is limited by the spatial distances and general hardware interfaces between the processor and the memory modules on the <a href="Motherboard" title="Motherboard">motherboard</a></li>
<li>Disk (<a href="Virtual_memory" title="Virtual memory">virtual memory</a>, <a href="File_system" title="File system">file system</a>) (1&nbsp;GB to 256&nbsp;<a href="Terabyte" class="mw-redirect" title="Terabyte">TB</a>) – very slow, due to the narrower (in bit width), physically much longer data channel between the main board of the computer and the disk devices, and due to the extraneous software protocol needed on the top of the slow hardware interface</li>
<li>Remote memory (other computers or the cloud) (practically unlimited) – speed varies from very slow to extremely slow</li></ul>
<p>Modern machines tend to read blocks of lower memory into the next level of the memory hierarchy. If this displaces used memory, the <a href="Operating_system" title="Operating system">operating system</a> tries to predict which data will be accessed least (or latest) and move it down the memory hierarchy. Prediction algorithms tend to be simple to reduce hardware complexity, though they are becoming somewhat more complicated.
</p>
<div class="mw-heading mw-heading3"><h3 id="Matrix_multiplication">Matrix multiplication</h3></div>
<p>A common example is <a href="Matrix_multiplication_algorithm" title="Matrix multiplication algorithm">matrix multiplication</a>:
</p>
<div class="mw-highlight mw-highlight-lang-pascal mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">n</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">m</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">p</span>
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">B</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">;</span>
</pre></div>
<p>By switching the looping order for <code>j</code> and <code>k</code>, the speedup in large matrix multiplications becomes dramatic, at least for languages that put contiguous array elements in the last dimension. This will not change the mathematical result, but it improves efficiency. In this case, "large" means, approximately, more than 100,000 elements in each matrix, or enough addressable memory such that the matrices will not fit in L1 and L2 caches.
</p>
<div class="mw-highlight mw-highlight-lang-pascal mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">n</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">p</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">m</span>
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">B</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">;</span>
</pre></div>
<p>The reason for this speedup is that in the first case, the reads of <code>A[i][k]</code> are in cache (since the <code>k</code> index is the contiguous, last dimension), but <code>B[k][j]</code> is not, so there is a cache miss penalty on <code>B[k][j]</code>. <code>C[i][j]</code> is irrelevant, because it can be <a href="Loop-invariant_code_motion" title="Loop-invariant code motion">hoisted</a> out of the inner loop -- the loop variable there is <code>k</code>.
</p>
<div class="mw-highlight mw-highlight-lang-pascal mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">n</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">m</span>
<span class="w"> </span><span class="n">temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">p</span>
<span class="w"> </span><span class="n">temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">temp</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">B</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">;</span>
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">temp</span>
</pre></div>
<p>In the second case, the reads and writes of <code>C[i][j]</code> are both in cache, the reads of <code>B[k][j]</code> are in cache, and the read of <code>A[i][k]</code> can be hoisted out of the inner loop.
</p>
<div class="mw-highlight mw-highlight-lang-pascal mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="k">for</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">n</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">p</span>
<span class="w"> </span><span class="n">temp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">m</span>
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">temp</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">B</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">;</span>
</pre></div>
<p>Thus, the second example has no cache miss penalty in the inner loop while the first example has a cache penalty.
</p><p>On a year 2014 processor, the second case is approximately five times faster than the first case, when written in <a href="C_(programming_language)" title="C (programming language)">C</a> and compiled with <code>gcc -O3</code>. (A careful examination of the disassembled code shows that in the first case, <a href="GNU_Compiler_Collection" title="GNU Compiler Collection">GCC</a> uses <a href="SIMD" class="mw-redirect" title="SIMD">SIMD</a> instructions and in the second case it does not, but the cache penalty is much worse than the SIMD gain.)
</p><p>Temporal locality can also be improved in the above example by using a technique called <a href="Loop_blocking" class="mw-redirect" title="Loop blocking">blocking</a>. The larger matrix can be divided into evenly sized sub-matrices, so that the smaller blocks can be referenced (multiplied) several times while in memory. Note that this example works for square matrices of dimensions SIZE x SIZE, but it can easily be extended for arbitrary matrices by substituting SIZE_I, SIZE_J and SIZE_K where appropriate.
</p>
<div class="mw-highlight mw-highlight-lang-pascal mw-content-ltr mw-highlight-lines" dir="ltr"><pre><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">ii</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="o">;</span><span class="w"> </span><span class="n">ii</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">SIZE</span><span class="o">;</span><span class="w"> </span><span class="n">ii</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">BLOCK_SIZE</span><span class="p">)</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">kk</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="o">;</span><span class="w"> </span><span class="n">kk</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">SIZE</span><span class="o">;</span><span class="w"> </span><span class="n">kk</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">BLOCK_SIZE</span><span class="p">)</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">jj</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="o">;</span><span class="w"> </span><span class="n">jj</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">SIZE</span><span class="o">;</span><span class="w"> </span><span class="n">jj</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="n">BLOCK_SIZE</span><span class="p">)</span>
<span class="w"> </span><span class="n">maxi</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="n">ii</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">BLOCK_SIZE</span><span class="o">,</span><span class="w"> </span><span class="n">SIZE</span><span class="p">)</span><span class="o">;</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ii</span><span class="o">;</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">maxi</span><span class="o">;</span><span class="w"> </span><span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="w"> </span><span class="n">maxk</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="n">kk</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">BLOCK_SIZE</span><span class="o">,</span><span class="w"> </span><span class="n">SIZE</span><span class="p">)</span><span class="o">;</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">kk</span><span class="o">;</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">maxk</span><span class="o">;</span><span class="w"> </span><span class="n">k</span><span class="o">++</span><span class="p">)</span>
<span class="w"> </span><span class="n">maxj</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">min</span><span class="p">(</span><span class="n">jj</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">BLOCK_SIZE</span><span class="o">,</span><span class="w"> </span><span class="n">SIZE</span><span class="p">)</span><span class="o">;</span>
<span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">jj</span><span class="o">;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">maxj</span><span class="o">;</span><span class="w"> </span><span class="n">j</span><span class="o">++</span><span class="p">)</span>
<span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">C</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">A</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">B</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">;</span>
</pre></div>
<p>The temporal locality of the above solution is provided because a block can be used several times before moving on, so that it is moved in and out of memory less often. Spatial locality is improved because elements with consecutive memory addresses tend to be pulled up the memory hierarchy together.
</p>
<div class="mw-heading mw-heading2"><h2 id="See_also">See also</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1266661725">
/* start https://en.wikipedia.org/ */


.mw-parser-output .portalbox{padding:0;margin:0.5em 0;display:table;box-sizing:border-box;max-width:175px;list-style:none}.mw-parser-output .portalborder{border:1px solid var(--border-color-base,#a2a9b1);padding:0.1em;background:var(--background-color-neutral-subtle,#f8f9fa)}.mw-parser-output .portalbox-entry{display:table-row;font-size:85%;line-height:110%;height:1.9em;font-style:italic;font-weight:bold}.mw-parser-output .portalbox-image{display:table-cell;padding:0.2em;vertical-align:middle;text-align:center}.mw-parser-output .portalbox-link{display:table-cell;padding:0.2em 0.2em 0.2em 0.3em;vertical-align:middle}@media(min-width:720px){.mw-parser-output .portalleft{margin:0.5em 1em 0.5em 0}.mw-parser-output .portalright{clear:right;float:right;margin:0.5em 0 0.5em 1em}}


/* end https://en.wikipedia.org/ */
</style>
<ul><li><a href="Cache-oblivious_algorithm" title="Cache-oblivious algorithm">Cache-oblivious algorithm</a></li>
<li><a href="Communication-avoiding_algorithm" title="Communication-avoiding algorithm">Communication-avoiding algorithm</a></li>
<li><a href="File_system_fragmentation" title="File system fragmentation">File system fragmentation</a></li>
<li><a href="Partitioned_global_address_space" title="Partitioned global address space">Partitioned global address space</a></li>
<li><a href="Row-_and_column-major_order" title="Row- and column-major order">Row- and column-major order</a></li>
<li><a href="Scalable_locality" title="Scalable locality">Scalable locality</a></li>
<li><a href="Scratchpad_memory" title="Scratchpad memory">Scratchpad memory</a></li>
<li><a href="Working_set" title="Working set">Working set</a></li>
<li><a href="Heuristic" title="Heuristic">Heuristic</a></li>
<li><a href="Locality-sensitive_hashing" title="Locality-sensitive hashing">Locality-sensitive hashing</a></li></ul>
<div class="mw-heading mw-heading2"><h2 id="References">References</h2></div>
<style data-mw-deduplicate="TemplateStyles:r1239543626">
/* start https://en.wikipedia.org/ */


.mw-parser-output .reflist{margin-bottom:0.5em;list-style-type:decimal}@media screen{.mw-parser-output .reflist{font-size:90%}}.mw-parser-output .reflist .references{font-size:100%;margin-bottom:0;list-style-type:inherit}.mw-parser-output .reflist-columns-2{column-width:30em}.mw-parser-output .reflist-columns-3{column-width:25em}.mw-parser-output .reflist-columns{margin-top:0.3em}.mw-parser-output .reflist-columns ol{margin-top:0}.mw-parser-output .reflist-columns li{page-break-inside:avoid;break-inside:avoid-column}.mw-parser-output .reflist-upper-alpha{list-style-type:upper-alpha}.mw-parser-output .reflist-upper-roman{list-style-type:upper-roman}.mw-parser-output .reflist-lower-alpha{list-style-type:lower-alpha}.mw-parser-output .reflist-lower-greek{list-style-type:lower-greek}.mw-parser-output .reflist-lower-roman{list-style-type:lower-roman}


/* end https://en.wikipedia.org/ */
</style><div class="reflist">
<div class="mw-references-wrap"><ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><b><a href="#cite_ref-1">^</a></b></span> <span class="reference-text">Not to be confused with the <a href="Principle_of_locality" title="Principle of locality">principle of locality</a> o=s*v=411##sts in physics.</span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><b><a href="#cite_ref-2">^</a></b></span> <span class="reference-text"><style data-mw-deduplicate="TemplateStyles:r1238218222">
/* start https://en.wikipedia.org/ */


.mw-parser-output cite.citation{font-style:inherit;word-wrap:break-word}.mw-parser-output .citation q{quotes:"\"""\"""'""'"}.mw-parser-output .citation:target{background-color:rgba(0,127,255,0.133)}.mw-parser-output .id-lock-free.id-lock-free a{background:url("./mw/Lock-green.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-limited.id-lock-limited a,.mw-parser-output .id-lock-registration.id-lock-registration a{background:url("./mw/Lock-gray-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .id-lock-subscription.id-lock-subscription a{background:url("./mw/Lock-red-alt-2.svg")right 0.1em center/9px no-repeat}.mw-parser-output .cs1-ws-icon a{background:url("./mw/Wikisource-logo.svg")right 0.1em center/12px no-repeat}body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-free a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-limited a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-registration a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .id-lock-subscription a,body:not(.skin-timeless):not(.skin-minerva) .mw-parser-output .cs1-ws-icon a{background-size:contain;padding:0 1em 0 0}.mw-parser-output .cs1-code{color:inherit;background:inherit;border:none;padding:inherit}.mw-parser-output .cs1-hidden-error{display:none;color:var(--color-error,#d33)}.mw-parser-output .cs1-visible-error{color:var(--color-error,#d33)}.mw-parser-output .cs1-maint{display:none;color:#085;margin-left:0.3em}.mw-parser-output .cs1-kern-left{padding-left:0.2em}.mw-parser-output .cs1-kern-right{padding-right:0.2em}.mw-parser-output .citation .mw-selflink{font-weight:inherit}@media screen{.mw-parser-output .cs1-format{font-size:95%}html.skin-theme-clientpref-night .mw-parser-output .cs1-maint{color:#18911f}}@media screen and (prefers-color-scheme:dark){html.skin-theme-clientpref-os .mw-parser-output .cs1-maint{color:#18911f}}


/* end https://en.wikipedia.org/ */
</style><cite id="CITEREFWilliam.2010" class="citation book cs1">William., Stallings (2010). <i>Computer organization and architecture&nbsp;: designing for performance</i> (8th&nbsp;ed.). Upper Saddle River, NJ: Prentice Hall. <a href="ISBN_(identifier)" class="mw-redirect" title="ISBN (identifier)">ISBN</a>&nbsp;<bdi>9780136073734</bdi>. <a href="OCLC_(identifier)" class="mw-redirect" title="OCLC (identifier)">OCLC</a>&nbsp;<a rel="nofollow" class="external text" href="https://search.worldcat.org/oclc/268788976">268788976</a>.</cite></span>
</li>
<li id="cite_note-NistBig1-3"><span class="mw-cite-backlink">^ <a href="#cite_ref-NistBig1_3-0"><sup><i><b>a</b></i></sup></a> <a href="#cite_ref-NistBig1_3-1"><sup><i><b>b</b></i></sup></a></span> <span class="reference-text">"NIST Big Data Interoperability Framework: Volume 1", [<a rel="nofollow" class="external free" href="https://doi.org/10.6028/NIST.SP.1500-1r2">https://doi.org/10.6028/NIST.SP.1500-1r2</a> <a rel="nofollow" class="external free" href="urn:doi:10.6028/NIST.SP.1500-1r2">urn:doi:10.6028/NIST.SP.1500-1r2</a></span>
</li>
<li id="cite_note-4"><span class="mw-cite-backlink"><b><a href="#cite_ref-4">^</a></b></span> <span class="reference-text">Aho, Lam, Sethi, and Ullman. "Compilers: Principles, Techniques &amp; Tools" 2nd ed. Pearson Education, Inc. 2007</span>
</li>
</ol></div></div>
<div class="mw-heading mw-heading2"><h2 id="Bibliography">Bibliography</h2></div>
<ul><li><a href="Peter_J._Denning" title="Peter J. Denning">Peter J. Denning</a>, <a rel="nofollow" class="external text" href="http://denninginstitute.com/pjd/PUBS/CACMcols/cacmJul05.pdf">"The Locality Principle"</a>, <i>Communications of the ACM</i>, Volume 48, Issue 7, (2005), Pages 19–24</li>
<li>Peter J. Denning, Stuart C. Schwartz, <a rel="nofollow" class="external text" href="http://denninginstitute.com/pjd/PUBS/WSProp_1972.pdf">"Properties of the Working-Set Model"</a>, <i>Communications of the ACM</i>, Volume 15, Issue 3 (March 1972), Pages 191–198</li></ul></div><!--htdig_noindex--><div><div class="zim-footer">
This article is issued from <a class="external text" title="Last edited on 2025-07-21" href="https://en.wikipedia.org/wiki/?title=Locality_of_reference&amp;oldid=1301666316">Wikipedia</a>. The text is available under <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.en">Creative Commons Attribution-Share Alike 4.0</a> unless otherwise noted. Additional terms may apply for the media files.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>

</body></html>